﻿using System;
using System.Linq.Expressions;

namespace Furiant.Figment.Agents
{
    public class Stat<T> where T:IComparable
    {
        private Func<IHasStats<T>, IComparable<T>> _function;
        private T _value;
        
        /// <summary>
        /// Creates a new instance whose IComparable&lt;T&gt; Value that can be read and set.
        /// </summary>
        internal Stat(T value)
        {
            _value = value;
        }

        /// <summary>
        /// Creates a new instance whose IComparable&lt;T&gt; Value is the result of a function.
        /// </summary>
        internal Stat(Func<IHasStats<T>, IComparable<T>> function)
        {
            _function = function;
            _value = default(T);
        }


        public T Value
        {
            get { return IsCalculated ? (T)_function((IHasStats<T>)_function.Target) : _value; }
            set
            {
                if (IsCalculated)
                {
                    throw new InvalidOperationException("The Value of this instance is the result of a function.");
                }
                _value = value;
            }
        }

        public Func<IHasStats<T>, IComparable<T>> Function { get { return _function; } internal set { _function = value; } }

        public bool IsCalculated { get { return _function != null; } }
    }
}
